<?php

/***  DOCUMENTATION LAYER

Klenwell Scissorhands (string-cutting) Library

Last Update: Oct 2007
Author: Tom at klenwell@gmail.com

FUNCTIONS
last_index_of($haystack, $needle, $offset=0)
substr_by_last_index($haystack, $needle, $keep_needle=0, $offset=0)
clip_head_by_fio($haystack, $needle, $keep_needle=1, $offset=0)
clip_tail_by_lio($haystack, $needle, $keep_needle=0, $offset=0)
get_teaser($text, $max_strlen)

NOTES

______________________________________________________________________________*/


// last_index_of: strrpos where needle can be str (not just char)
// based on super_conforming_strrpos: http://www.php.net/manual/en/function.strrpos.php#74474
/*____________________________________________________________________________*/
function last_index_of($haystack, $needle, $offset=0)
{
  // we're super-conforming here
  if( !is_string($needle) ) $needle = ord(intval($needle));
  if( !is_string($haystack) ) $haystack = strval($haystack);
  
  // setup
  $offset = intval($offset);
  $hlen = strlen($haystack);
  $nlen = strlen($needle);
  
  // sanity checks
  if( $nlen == 0 )
  {
    trigger_error(__FUNCTION__.'(): Empty delimiter.', E_USER_WARNING);
    return false;
  }
  elseif( $offset >= $hlen )
  {
    trigger_error(__FUNCTION__.'(): Offset not contained in string.', E_USER_WARNING);
    return false;
  }
  if( $offset < 0 )
  {
    $haystack = substr($haystack, -$offset);
    $offset = 0;
  }
  
  // into the looking glass
  $hrev = strrev($haystack);
  $nrev = strrev($needle);
  
  // search
  $pos = strpos($hrev, $nrev, $offset);
  if( $pos === false ) return false;
  else return $hlen - $nlen - $pos;
}
/*____________________________________________________________________________*/



// substr_by_last_index
// locates last occurrence of needle and cuts off everything after it 
// inclusive dictates whether or not 
/*____________________________________________________________________________*/
function substr_by_last_index($haystack, $needle, $keep_needle=0, $offset=0) 
{
  $clip = '';     // return

	$lio = last_index_of($haystack, $needle, $offset);
	if ( $lio === false ) return false;
  
  $clip = substr($haystack, $lio);
	if ( !$keep_needle ) $clip = substr($clip, strlen($needle));
	
	return $clip;
}
/*____________________________________________________________________________*/



// clip_head_by_fio
// clip head off haystack at first index of needle (glorified substr)
/*____________________________________________________________________________*/
function clip_head_by_fio($haystack, $needle, $keep_needle=1, $offset=0)
{
  $clip = '';   // return
  
  $idx_offset = ( $keep_needle ) ? 0 : strlen($needle);
  $clip = substr($haystack, strpos($haystack,$needle) + $idx_offset);
  
  return $clip;
} 
/*____________________________________________________________________________*/



// clip_tail_by_lio
// locates last occurrence of needle and cuts off everything *before* it 
// inclusive dictates whether or not 
/*____________________________________________________________________________*/
function clip_tail_by_lio($haystack, $needle, $keep_needle=0, $offset=0) 
{
  $clip = '';     // return

	$lio = last_index_of($haystack, $needle, $offset);
	if ( $lio === false ) return false;
  
  if ( $keep_needle ) $lio = $lio + strlen($needle);
  
  $clip = substr($haystack, 0, $lio);
	return $clip;
}
/*____________________________________________________________________________*/



// get_teaser
// builds a short teaser or blurb no longer than max_strlen from a longer string 
/*____________________________________________________________________________*/
function get_teaser($text, $max_strlen)
{
  $excerpt = '';  // return
  
  $_REGEX['excerpt'] = '%^([\s\S]){1,' . $max_strlen . '}([\s\.\?!,])+%i';
  $_strlen = 0;
  $_stripped_text = '';
  $_EXCERPT = array();
    
  $text = preg_replace('%<br[^>]*>%', ' ', $text);  
  $text = strip_tags($text);
  $text = preg_replace('%[\n\r]%', ' ', $text);
  $_strlen = strlen($text);
  
  if ( $_strlen <= $max_strlen ) return $text;
  
  $_stripped_text = strip_tags($text);
  
  $num_matches = preg_match($_REGEX['excerpt'], $_stripped_text, $_EXCERPT);
  $_cliplen = -(strlen($_EXCERPT[2]));
  $excerpt = substr($_EXCERPT[0], 0, $_cliplen);
  
  $excerpt = $excerpt . '...';
  return $excerpt;
}
/*____________________________________________________________________________*/



// Testbed
/*____________________________________________________________________________*/

if ( 1 )
{
  print '<pre>';

  // test strings
  $TEST = array('dfa38dg2a7366xneedle1832974needle2djfioe3wn2na', 'needle');
  
  // last_index_of
  print "<br>last_index_of: {$TEST[0]} > {$TEST[1]} -> ";
  print last_index_of($TEST[0], $TEST[1], $offset = 0);
  print '<hr>';

  // substr_by_last_index
  print "<br>substr_by_last_index: {$TEST[0]} > {$TEST[1]} -> ";
  print substr_by_last_index($TEST[0], $TEST[1], $keep_needle=0);
  print "<br>substr_by_last_index (keep needle): {$TEST[0]} > {$TEST[1]} -> ";
  print substr_by_last_index($TEST[0], $TEST[1], $keep_needle=1);
  print '<hr>';
  
  // clip_head_by_fio($haystack, $needle, $offset=0)
  print "<br>clip_head_by_fio: {$TEST[0]} > {$TEST[1]} -> ";
  print clip_head_by_fio($TEST[0], $TEST[1], $keep_needle=0);
  print "<br>clip_head_by_fio (keep needle): {$TEST[0]} > {$TEST[1]} -> ";
  print clip_head_by_fio($TEST[0], $TEST[1], $keep_needle=1, $offset=0);
  print '<hr>';
  
  // clip_tail_by_lio
  print "<br>clip_tail_by_lio: {$TEST[0]} > {$TEST[1]} -> ";
  print clip_tail_by_lio($TEST[0], $TEST[1], $keep_needle=0);
  print "<br>clip_tail_by_lio (keep needle): {$TEST[0]} > {$TEST[1]} -> ";
  print clip_tail_by_lio($TEST[0], $TEST[1], $keep_needle=1);
  print '<hr>';
  
  // get_teaser
  $long_str = 'This is a string of over 12 words and<br />a length in excess of 80 characters that we will reduce<br>to less than 40 characters!';
  print "<br>get_teaser: $long_str -> ";
  print get_teaser($long_str, 40);
  print '<hr>';
  
  print '</pre>';
}

/*____________________________________________________________________________*/

?>
